// Manage the behaviour of actors
//--------------------------------
#ifndef BEHAVIOUR_H
#define BEHAVIOUR_H
#include "common.h"

// Generic behaviour interface. Subclasses of BI represent
// different behaviours that can be implemented.
// Behaviours may have up to 8 arguments.
template< typename Arg0 = int, typename Arg1 = int, typename Arg2 = int, typename Arg3 = int,
          typename Arg4 = int, typename Arg5 = int, typename Arg6 = int, typename Arg7 = int >
class BI {
public:

    typedef Arg0 ArgType0;
    typedef Arg1 ArgType1;
    typedef Arg2 ArgType2;
    typedef Arg3 ArgType3;
    typedef Arg4 ArgType4;
    typedef Arg5 ArgType5;
    typedef Arg6 ArgType6;
    typedef Arg7 ArgType7;

    // This function should be overriden to call a specifically-named
    // virtual function provided in the derived interface.
    // A BIImplementer can then inherit and override this function.
    // Naming convention - interface BIFoo provides
    //     virtual bool Foo( const BIArgs& args ) = 0;
    virtual bool ICall( Arg0 a0, Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4, Arg5 a5, Arg6 a6, Arg7 a7 ) = 0;

    // The behaviour chain is as follows - when an actor's behaviour is
    // requested, first any preActor buffs that implement the behaviour are called.
    // Then, the actor's behaviour is called. Then, any postActor buffs are called.
    // Buffs are called in order of their priority.
    // A return value of true from a behaviour implementation indicates that
    // the behaviour chain should continue, false makes it halt.

};
// Identical, but provides a const interface.
template< typename Arg0 = int, typename Arg1 = int, typename Arg2 = int, typename Arg3 = int,
          typename Arg4 = int, typename Arg5 = int, typename Arg6 = int, typename Arg7 = int >
class BIConst {
public:

    typedef Arg0 ArgType0;
    typedef Arg1 ArgType1;
    typedef Arg2 ArgType2;
    typedef Arg3 ArgType3;
    typedef Arg4 ArgType4;
    typedef Arg5 ArgType5;
    typedef Arg6 ArgType6;
    typedef Arg7 ArgType7;

    virtual bool ICall( Arg0 a0, Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4, Arg5 a5, Arg6 a6, Arg7 a7 ) const = 0;

};

#define BEHAVIOUR_CALL virtual bool ICall( ArgType0 a0, ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7 )
#define BEHAVIOUR_START static void Start( ArgType0 a0, ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7 )
#define BEHAVIOUR_END   static void End(   ArgType0 a0, ArgType1 a1, ArgType2 a2, ArgType3 a3, ArgType4 a4, ArgType5 a5, ArgType6 a6, ArgType7 a7 )

#endif
